﻿using HECore.Account.Contract.Models.Account.Inputs;
using HECore.Account.Share;
using HECore.Admin.WebApi.Models.Emoloyees.Dtos;
using HECore.Admin.WebApi.Models.Emoloyees.Inputs;
using HECore.ServiceFrame.Attributes;
using HECore.ServiceFrame.Filters;
using HECore.ServiceFrame.Models;
using HECore.ServiceFrame.Redis;
using HECore.Tenant.Contract.Models.Emoloyees.Dtos;
using HECore.Tenant.Contract.Models.Emoloyees.Inputs;
using HECore.Tenant.Share;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace HECore.Admin.WebApi.Controllers
{
    /// <summary>
    /// 员工接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        private readonly FrameRedisClient _redisClient;
        private readonly IAccountService _accountService;
        private readonly IEmoloyeeService _emoloyeeService;

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="redisClient"></param>
        /// <param name="accountService"></param>
        /// <param name="emoloyeeService"></param>
        public EmployeeController(
            FrameRedisClient redisClient,
            IAccountService accountService,
            IEmoloyeeService emoloyeeService)
        {
            _redisClient = redisClient;
            _accountService = accountService;
            _emoloyeeService = emoloyeeService;
        }

        /// <summary>
        /// 员工登录：第一步获取登录凭证code
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("login/get-code")]
        [Audited]
        public async Task<GetLoginCodeDto> GetLoginCode([FromBody] AccountLoginInput input)
        {
            // 账号登录
            var account = await _accountService.Login(input);
            // 账号员工
            var emoloyees = await _emoloyeeService.GetAccountEmoloyees(account.Id);
            if (emoloyees == null || emoloyees.Count() == 0) throw new UserFriendlyException("no.join.tenant", "当前账号没有加入任何租户");
            // 添加Code到Redis
            var dto = new GetLoginCodeDto() { CodeInfo = new LoginCodeDto() { Code = Guid.NewGuid(), CodeExpireMinute = 5 }, Employees = emoloyees };
            _redisClient.StringSetExpiry($"emoloyee:login:code:{dto.CodeInfo.Code}", JsonConvert.SerializeObject(dto), TimeSpan.FromMinutes(dto.CodeInfo.CodeExpireMinute));
            return dto;
        }

        /// <summary>
        /// 员工登录：第二步通过登录凭证code换取授权token
        /// </summary>
        /// <returns></returns>
        [HttpPost("login/get-token")]
        [Audited]
        public async Task<GetLoginTokenDto> GetAuthorizeToken([FromBody] GetAuthorizeTokenInput input)
        {
            //验证code是否存在
            bool exists = await _redisClient.KeyExistsAsync($"emoloyee:login:code:{input.Code}");
            if (!exists) throw new UserFriendlyException("code.invalid", "登录凭证已失效");

            //获取code缓存信息
            var value = await _redisClient.StringGetAsync($"emoloyee:login:code:{input.Code}");
            await _redisClient.KeyDeleteAsync($"emoloyee:login:code:{input.Code}");
            var model = JsonConvert.DeserializeObject<GetLoginCodeDto>(value);

            //获取选择登录租户
            var employee = model.Employees.Where(x => x.TenantId == input.TenantId).FirstOrDefault();
            if (employee == null) throw new UserFriendlyException("no.join.tenant", "当前账号没有加入当前租户");
            if (employee.EmployeeState == Tenant.Contract.Enums.EmployeeStateEnum.Disable) new UserFriendlyException("no.join.tenant", "当前账号没有加入当前租户");

            //查询员工权限
            var permissions = await _emoloyeeService.GetEmployeePermissions(employee.Id, employee.TenantId);
            employee.IsAdministrator = permissions.IsAdministrator;
            employee.Permissions = permissions.Permissions;

            //登录Token信息
            var loginToken = new GetLoginTokenDto()
            {
                token = new LoginTokenDto()
                {
                    Token = Guid.NewGuid(),
                    TokenExpireHour = 2,
                    RefreshToken = Guid.NewGuid(),
                    RefreshTokenExpireHour = 15 * 24,
                },
                employee = employee
            };

            //缓存当前用户信息
            var currentUser = new CurrentEmployee()
            {
                AccountId = employee.AccountId,
                EmployeeFullName = employee.EmployeeFullName,
                EmployeeId = employee.Id,
                TenantId = employee.TenantId,
                TenantName = employee.TenantName,
                IsAdministrator = permissions.IsAdministrator,
                EmployeePermissions = permissions.Permissions
            };
            await _redisClient.StringSetExpiryAsync($"emoloyee:login:token:{loginToken.token.Token}", JsonConvert.SerializeObject(currentUser), TimeSpan.FromHours(loginToken.token.TokenExpireHour));

            //记录员工登录Token信息
            var time = DateTime.Now;
            string ipaddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
            if (Request.Headers.ContainsKey("X-Real-IP"))
            {
                ipaddress = Request.Headers["X-Real-IP"].ToString();
            }
            if (Request.Headers.ContainsKey("X-Forwarded-For"))
            {
                ipaddress = Request.Headers["X-Forwarded-For"].ToString();
            }
            await _emoloyeeService.SetToken(new SetTokenInput()
            {
                EmployeeId = employee.Id,
                RefreshToken = loginToken.token.RefreshToken,
                RefreshTokenExpireTime = time.AddHours(loginToken.token.RefreshTokenExpireHour),
                TenantId = employee.TenantId,
                Token = loginToken.token.Token,
                TokenExpireTime = time.AddHours(loginToken.token.TokenExpireHour),
            });

            return loginToken;
        }
    }
}